package org.tools.wstt.listener;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.tools.wstt.reference.ApplicationComponent;
import org.tools.wstt.utils.logger.IWsttLogger;
import org.tools.wstt.utils.logger.WsttLoggerFactory;

/**
 * Application Lifecycle Listener implementation class AppListener
 * 
 */
public class AppListener implements ServletContextListener,
		ApplicationComponent {

	private ServletContext mContext = null;

	protected IWsttLogger mLogger;

	/**
	 * Default constructor.
	 */
	public AppListener() {
	}

	public void contextInitialized(ServletContextEvent event) {
		this.mLogger = WsttLoggerFactory.getLogger(this.getClass());
		mContext = event.getServletContext();
		log("Initializing");
		// Special init parameter to preconfigure the application.
		String s = mContext.getInitParameter("redirectURL");

		if (s != null) {
			mContext.log("INIT Parameter [Redirect URL] not null");
			try {
				URL url = new URL(s);
				setAttribute("destProtocol", url.getProtocol());
				setAttribute(APP_CONFIG_PROXY_DEST_HOST, url.getHost());
				setAttribute(APP_CONFIG_PROXY_DEST_PORT, "" + url.getPort());
				if (url.getPort() == -1) {
					setAttribute("destPort", "80");
				}
			} catch (MalformedURLException malformedurlexception) {
			}
		}

		// Configuration from Temporary Properties File
		try {
			Properties vProps = new Properties();
			String vConfigFilePath = System.getProperty("java.io.tmpdir") + "/"
					+ APP_CONFIG_PREDEF_FILE;
			log("Try to load configuration from file : " + vConfigFilePath);
			vProps.load(new FileInputStream(vConfigFilePath));
			if (vProps.containsKey(APP_CONFIG_PROXY_DEST_HOST)) {
				setAttribute(APP_CONFIG_PROXY_DEST_HOST, vProps
						.get(APP_CONFIG_PROXY_DEST_HOST));
				log(APP_CONFIG_PROXY_DEST_HOST + " loaded from properties file");
			}
			if (vProps.containsKey(APP_CONFIG_PROXY_DEST_PORT)) {
				setAttribute(APP_CONFIG_PROXY_DEST_PORT, vProps
						.get(APP_CONFIG_PROXY_DEST_PORT));
				log(APP_CONFIG_PROXY_DEST_PORT + " loaded from properties file");
			}
		} catch (IOException e) {
			log("No Properties file to load");
		}

		loadVersionProperties();

		// initialize buffer list for temporary storage of proxy calls
		List vList = new ArrayList();
		mContext.setAttribute(APP_PROXY_CALLS, vList);
		mContext.setAttribute(APP_PROXY_CALLS_TOTAL_COUNT, new Integer(0));
		mContext.setAttribute(APP_PROXY_CALLS_TOTAL_TIME, new Long(0));
		mContext.setAttribute(APP_RESPONSES_MAPS, new HashMap());
		mContext.setAttribute(APP_PROBE_RESULTS, new ArrayList());
		mContext.setAttribute(APP_REQUEST_RESULTS, new ArrayList());
	}

	public void setAttribute(String pKey, Object pValueObject) {
		mContext.setAttribute(pKey, pValueObject);
		log((String) mContext.getAttribute(pKey));
	}

	public void contextDestroyed(ServletContextEvent event) {
		log((String) mContext.getAttribute("Counter"));
		mContext.removeAttribute("Counter");
	}

	/**
	 * 
	 */
	public void log(String pMessage) {
		if (this.mLogger != null) {
			this.mLogger.info(pMessage);
		}
		mContext.log(pMessage);
	}

	/**
	 * 
	 * @param pMessage
	 * @param pThrowable
	 */
	protected void logError(String pMessage, Throwable pThrowable) {
		StringBuffer vSB = new StringBuffer(pMessage);
		vSB.append(" : ");
		vSB.append(pThrowable.getMessage());
		if (this.mLogger != null) {
			this.mLogger.error(vSB.toString());
		}
		mContext.log(vSB.toString());

		if (this.mLogger != null && this.mLogger.isDebugEnabled()) {
			this.mLogger.debug("Details : ", pThrowable);
		}
	}

	protected void loadVersionProperties() {
		// Configuration from Version Properties File
		try {
			Properties vProps = new Properties();
			vProps.load(this.getClass().getClassLoader().getResourceAsStream(
					"/" + APP_VERSION_FILE));
			if (vProps.containsKey(APP_CONFIG_BUILD_DATE)) {
				setAttribute(APP_CONFIG_BUILD_DATE, vProps
						.get(APP_CONFIG_BUILD_DATE));
				log(APP_CONFIG_BUILD_DATE + " loaded from properties file");
			}
			if (vProps.containsKey(APP_CONFIG_BUILD_VERSION)) {
				setAttribute(APP_CONFIG_BUILD_VERSION, vProps
						.get(APP_CONFIG_BUILD_VERSION));
				log(APP_CONFIG_BUILD_VERSION + " loaded from properties file");
			}
		} catch (IOException e) {
			log("No Properties file to load");
		}
	}

}
